#!/usr/bin/env python3
#encoding=utf8

# 作者    ：李治华
# 日期    ：2019/6/18
# 文件    ：VerifyOfficialApk.py
# 联系    ：lizhihua1009@189.cn

import hashlib
import json
import os
import requests


# 读取配置文件
def readConfigAsDict(configFileName = "config.json"):
    with open("config.json", "r", encoding="utf-8") as config:
        return json.loads(config.read())

# 删除旧的 apk 文件
def delFileNameEndsWith(rootDir=os.getcwd(), fileNameEndsString=".apk"):
    count = 0
    print("=============删除文件=============")
    for root, dirs, files in os.walk(rootDir):
        for fileName in files:
            if (fileName.endswith(fileNameEndsString)):
                print(fileName)
                os.remove(fileName)
                count += 1
    if (count != 0):
        print("共删除 {0} 个文件。".format(count))
    else:
        print("没有可供删除的文件！")
    print("=============删除结束=============")


# 下载 Android 最新版本
def fileDonwload(url = ""):
    while (True):
        response = requests.get(url, allow_redirects=False)
        url = response.headers['Location']
        apkFileName = url.split('/')[-1]
        if (apkFileName.endswith('.apk')):
            break
    response = requests.get(url, allow_redirects=False)
    content = response.content
    with open(apkFileName, 'wb') as f:
        f.write(content)
        f.close()
    return apkFileName, url

# 获取指定文件的 MD5
def getMD5(fileName = ""):
    if (len(fileName) == 0):
        return "请输入文件绝对路径"
    if (not os.path.isfile(fileName)):
        return "文件不存在，请重新输入"
    if (not os.access(fileName, os.R_OK)):
        return "文件暂不可读，请稍后再试"
    fileSize = os.path.getsize(fileName)
    blockSize = 64 * 1024
    md5 = hashlib.md5()
    with open(fileName, "rb") as f:
        for count in range(0, int(fileSize / blockSize) + 1):
            md5.update(f.read(blockSize))
    return md5.hexdigest().upper()

# 比较 MD5
def verfiyMD5(sourceMD5, targetMD5):
    if (sourceMD5.upper() == targetMD5.upper()):
        return "官网下载 apk 的 MD5 与开发提供的 MD5 一致，验证通过！"
    return "官网下载 apk 的 MD5 与开发提供的 MD5 不一致，验证未通过！"


# 输出最终结果
def writeResultFile(result):
    with open("result.json", "w+", encoding="utf-8") as resultFile:
        resultFile.write(json.dumps(result, ensure_ascii=False,indent=4))
        resultFile.close()

# 钉钉机器人发送最终结果
def sendResult(result):
    config = readConfigAsDict(configFileName="config.json")
    url = config["DingTalkConfig"]["webhook"]
    headers = config["DingTalkConfig"]["headers"]
    data = config["DingTalkConfig"]["data"]
    data["text"]["content"] = json.dumps(result, ensure_ascii=False, indent=4)
    json_data = json.dumps(data)
    requests.post(url, headers=headers, data=json_data)

if __name__ == '__main__':
    result = {}
    config = readConfigAsDict(configFileName="config.json")
    delFileNameEndsWith(rootDir=os.getcwd(), fileNameEndsString=".apk")
    apkFileName, url = fileDonwload(config["AppliCationConfig"]["downloadURL"])
    sourceMD5 = getMD5(apkFileName)
    result["应用名称"] = config["AppliCationConfig"]["appName"]
    result["应用包名"] = config["AppliCationConfig"]["packageName"]
    result["下载的文件名"] = apkFileName
    result["开发提供的 MD5"] = config["AppliCationConfig"]["targetMD5"]
    result["实际下载文件的 MD5"] = sourceMD5
    result["官网下载地址"] = config["AppliCationConfig"]["downloadURL"]
    result["实际文件的下载地址"] = url
    result["验证结果"] = verfiyMD5(sourceMD5=sourceMD5, targetMD5=config["targetMD5"])
    writeResultFile(result)
    sendResult(result)
